package chatclient;

import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.Enumeration;
import javax.swing.*;
import model.Constantes;
import model.DataListItem;
import model.DataMssge;

/**
 *
 * @author carlos
 */
public class FChat extends javax.swing.JFrame {

    private ChatClient parent;
    private DefaultListModel lstModel;
    private boolean blnIsWriting = false;
    private FHistorial fHistorial = null;

    /**
     * Creates new form FChat
     */
    public FChat() {
        initComponents();
    }

    public FHistorial getfHistorial() {
        return fHistorial;
    }
   
    @Override
    public ChatClient getParent() {
        return parent;
    }
    

    FChat(ChatClient aThis) {
        initComponents();
        this.parent = aThis;
        lstModel = new DefaultListModel();
        lstCU.setModel(lstModel);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        lstCU = new javax.swing.JList();
        lblErrorMessage = new javax.swing.JLabel();
        txtMessage = new javax.swing.JTextField();
        jtpChatrooms = new javax.swing.JTabbedPane();
        cmdAddUserChatroom = new javax.swing.JButton();
        btnSendMessage = new javax.swing.JButton();
        btnLeaveRoom = new javax.swing.JButton();
        lblWelcome = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        btnShowhistory = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Chat Application - Chat room");
        setBackground(new java.awt.Color(0, 102, 204));
        setMinimumSize(new java.awt.Dimension(500, 295));
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
        });

        lstCU.setForeground(new java.awt.Color(51, 102, 255));
        lstCU.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                lstCUMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(lstCU);

        txtMessage.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                txtMessageKeyReleased(evt);
            }
        });

        jtpChatrooms.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

        cmdAddUserChatroom.setText("add");
        cmdAddUserChatroom.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdAddUserChatroomActionPerformed(evt);
            }
        });

        btnSendMessage.setLabel("Send");
        btnSendMessage.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSendMessageActionPerformed(evt);
            }
        });

        btnLeaveRoom.setText("close chat");
        btnLeaveRoom.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLeaveRoomActionPerformed(evt);
            }
        });

        jLabel1.setText("Connected users:");

        btnShowhistory.setText("show history");
        btnShowhistory.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnShowhistoryActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 137, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(33, 33, 33)
                        .addComponent(btnShowhistory))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(34, 34, 34)
                        .addComponent(jLabel1)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jtpChatrooms)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(lblWelcome, javax.swing.GroupLayout.PREFERRED_SIZE, 227, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(btnLeaveRoom))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(4, 4, 4)
                                .addComponent(lblErrorMessage, javax.swing.GroupLayout.DEFAULT_SIZE, 261, Short.MAX_VALUE))
                            .addComponent(txtMessage, javax.swing.GroupLayout.DEFAULT_SIZE, 265, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(cmdAddUserChatroom, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(btnSendMessage))
                        .addContainerGap())))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnLeaveRoom, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lblWelcome)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jtpChatrooms, javax.swing.GroupLayout.DEFAULT_SIZE, 180, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(lblErrorMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 13, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(cmdAddUserChatroom, javax.swing.GroupLayout.PREFERRED_SIZE, 13, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addComponent(jScrollPane1))
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(txtMessage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(btnSendMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnShowhistory, javax.swing.GroupLayout.PREFERRED_SIZE, 12, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnLeaveRoomActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLeaveRoomActionPerformed
        DataMssge datos = new DataMssge();
        if (jtpChatrooms.getTabCount() > 0) {
            // Get the index of the currently selected tab
            int selIndex = jtpChatrooms.getSelectedIndex();
            JPanel panel = (JPanel) jtpChatrooms.getComponentAt(selIndex);

            datos.setChatID(Integer.parseInt(panel.getName()));
            datos.setOption(Constantes.Eoption.leaveChatroom);
            datos.setUser(this.parent.getCurrentUser());
            datos.setStrLog(this.parent.getCurrentUser().getName() + " acaba de abandonar el chat.");

            jtpChatrooms.removeTabAt(selIndex);

            try {
                this.parent.getComm().sendRequest(datos);
            } catch (IOException ex) {
                Common.ErrorMessage("Error al mandar : " + ex.getMessage(), ex);
                this.parent.ConnectionClosed();
            }
        }
    }//GEN-LAST:event_btnLeaveRoomActionPerformed

    private void cmdAddUserChatroomActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdAddUserChatroomActionPerformed
        int selIndex = jtpChatrooms.getSelectedIndex();
        int intChatID;

        if (jtpChatrooms.getTabCount() > 0) {
            if (selIndex >= 0) {
                JPanel panel = (JPanel) jtpChatrooms.getComponentAt(selIndex);
                intChatID = Integer.parseInt(panel.getName());

                this.sendChatRequest(intChatID);
            }
        }
    }//GEN-LAST:event_cmdAddUserChatroomActionPerformed

    private void lstCUMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lstCUMouseClicked
        // if double mouse click
        if (evt.getClickCount() == 2) {
            this.sendChatRequest(-1);
        }
    }//GEN-LAST:event_lstCUMouseClicked

    private void btnSendMessageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSendMessageActionPerformed
        this.sendChatMessage();
    }//GEN-LAST:event_btnSendMessageActionPerformed

    private void txtMessageKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtMessageKeyReleased
        int key = evt.getKeyCode();

        if (jtpChatrooms.getTabCount() > 0) {
            switch (key) {
                case KeyEvent.VK_ENTER:
                    this.sendChatMessage();
                    blnIsWriting = false;

                    //enviar ya no esta escribiendo ("")
                    this.sendLogMessage("");
                    break;
                case KeyEvent.VK_BACK_SPACE:
                    //cuando estaba escribiendo y ha borrado el contenido
                    if (txtMessage.getText().equals("") && blnIsWriting) {
                        blnIsWriting = false;

                        //enviar ya no esta escribiendo ("")
                        this.sendLogMessage("");
                    }
                default:
                    //esta escribiendo...
                    if (!txtMessage.getText().equals("") && !blnIsWriting) {
                        blnIsWriting = true;

                        //enviar esta escribiendo
                        this.sendLogMessage(this.parent.getCurrentUser().getName() + " is writing...");
                    }
                    break;
            }
        }
    }//GEN-LAST:event_txtMessageKeyReleased

    private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
        this.parent.showParent();
    }//GEN-LAST:event_formWindowClosed

    private void btnShowhistoryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnShowhistoryActionPerformed

        this.setEnabled(false);
        this.fHistorial = new FHistorial(this);
        Common.centerFrame(this.fHistorial);
        this.fHistorial.setVisible(true);

    }//GEN-LAST:event_btnShowhistoryActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(FChat.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(FChat.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(FChat.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(FChat.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new FChat().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnLeaveRoom;
    private javax.swing.JButton btnSendMessage;
    private javax.swing.JButton btnShowhistory;
    private javax.swing.JButton cmdAddUserChatroom;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTabbedPane jtpChatrooms;
    private javax.swing.JLabel lblErrorMessage;
    private javax.swing.JLabel lblWelcome;
    private javax.swing.JList lstCU;
    private javax.swing.JTextField txtMessage;
    // End of variables declaration//GEN-END:variables

    private void sendChatRequest(int intChatID) {
        DataMssge datos = new DataMssge();

        datos.setOption(Constantes.Eoption.peticionChat);
        datos.setUser(this.parent.getCurrentUser());

        for (Object lstItem : lstCU.getSelectedValues()) {
            datos.getUsers().put(((DataListItem) lstItem).getKey(), ((DataListItem) lstItem).getValue());
        }
        datos.setChatID(intChatID);

        try {
            this.parent.getComm().sendRequest(datos);
        } catch (IOException ex) {
            Common.ErrorMessage("Error al mandar : " + ex.getMessage(), ex);
            this.parent.ConnectionClosed();
        }
    }

    private void sendChatMessage() {
        DataMssge datos = new DataMssge();

        if (!txtMessage.getText().equals("") && (jtpChatrooms.getTabCount() > 0)) {
            // Get the index of the currently selected tab
            int selIndex = jtpChatrooms.getSelectedIndex();
            JPanel panel = (JPanel) jtpChatrooms.getComponentAt(selIndex);
            JScrollPane jscrollPane = (JScrollPane) panel.getComponent(0);
            JViewport jViewport = (JViewport) jscrollPane.getComponent(0);
            JTextArea jTextArea = (JTextArea) jViewport.getComponent(0);

            if (jTextArea.getText().equals("")) {
                jTextArea.setText(txtMessage.getText());
            } else {
                jTextArea.setText(jTextArea.getText() + System.getProperty("line.separator") + txtMessage.getText());
            }

            datos.setChatID(Integer.parseInt(panel.getName()));
            datos.setOption(Constantes.Eoption.mensajeChat);
            datos.setUser(this.parent.getCurrentUser());
            datos.setStrText(txtMessage.getText());

            try {
                this.parent.getComm().sendRequest(datos);
            } catch (IOException ex) {
                Common.ErrorMessage("Error al mandar : " + ex.getMessage(), ex);
                this.parent.ConnectionClosed();
            }

            txtMessage.setText("");
        }
    }

    public void openChatroom(DataMssge datos) {
        JPanel jPanel;
        JScrollPane jScrollPane;
        JTextArea jTextArea;
        StringBuilder label = new StringBuilder();
        String username;

        jPanel = new javax.swing.JPanel();
        jScrollPane = new javax.swing.JScrollPane();
        jTextArea = new javax.swing.JTextArea();
        jTextArea.setEditable(false);

        jTextArea.setColumns(20);
        jTextArea.setRows(5);
        jScrollPane.setViewportView(jTextArea);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel);
        jPanel.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(jScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 333, Short.MAX_VALUE));
        jPanel1Layout.setVerticalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(jScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 115, Short.MAX_VALUE));

        //get values
        jPanel.setName(String.valueOf(datos.getChatID()));

        Enumeration e = datos.getUsers().keys();

        while (e.hasMoreElements()) {
            username = (String) e.nextElement();

            if (!username.equals(this.parent.getCurrentUser().getUsername())) {
                if (label.toString().equals("")) {
                    label.append(datos.getUsers().get(username));
                } else {
                    label.append(", ").append(datos.getUsers().get(username));
                }
            }
        }

        jtpChatrooms.addTab(label.toString(), jPanel);
    }

    void setErrorLabel(String strLog) {
        lblErrorMessage.setText(strLog);
    }

    void refreshUCList(DataMssge datos) {
        DataListItem lstItem;
        String username;
        Enumeration e = datos.getUsers().keys();

        lstModel = (DefaultListModel) lstCU.getModel();
        lstModel.clear();

        //iterate through Hashtable keys Enumeration and send request to all users
        while (e.hasMoreElements()) {
            username = (String) e.nextElement();

            if (!username.equals(this.parent.getCurrentUser().getUsername())) {
                lstItem = new DataListItem();
                lstItem.setKey(username);
                lstItem.setValue((String) datos.getUsers().get(username));
                lstModel.addElement(lstItem);
            }
        }
    }

    void refreshChatUserList(DataMssge datos) {
        StringBuilder label = new StringBuilder("");
        int intCharAt = -1;
        String username;

        intCharAt = getChatRoomPosition(datos.getChatID());

        if (intCharAt == -1) {
            this.openChatroom(datos);
        } else {

            Enumeration e =  datos.getUsers().keys();

            while (e.hasMoreElements()) {
                username = (String) e.nextElement();

                if (!username.equals(this.parent.getCurrentUser().getUsername())) {
                    if (label.toString().equals("")) {
                        label.append(datos.getUsers().get(username));
                    } else {
                        label.append(", ").append(datos.getUsers().get(username));
                    }
                }
            }

            if (label.toString().equals("")) {
                jtpChatrooms.removeTabAt(intCharAt);
            } else {
                jtpChatrooms.setTitleAt(intCharAt, label.toString());
            }
        }
    }

    void sentChatMessage(DataMssge datos) {
        int intPosition = getChatRoomPosition(datos.getChatID());

        JPanel panel = (JPanel) jtpChatrooms.getComponentAt(intPosition);
        JScrollPane jscrollPane = (JScrollPane) panel.getComponent(0);
        JViewport jViewport = (JViewport) jscrollPane.getComponent(0);
        JTextArea jTextArea = (JTextArea) jViewport.getComponent(0);

        if (jTextArea.getText().equals("")) {
            jTextArea.setText(datos.getUser().getName() + ": " + datos.getStrText());
        } else {
            jTextArea.setText(jTextArea.getText() + System.getProperty("line.separator") + datos.getUser().getName() + ": " + datos.getStrText());
        }

        jTextArea.setCaretPosition(jTextArea.getDocument().getLength());
    }

    private int getChatRoomPosition(int chatID) {
        JPanel panel;
        int intPosition = -1;

        for (int i = 0; i < jtpChatrooms.getTabCount(); i++) {
            panel = (JPanel) jtpChatrooms.getComponentAt(i);
            if (panel.getName().equals(String.valueOf(chatID))) {
                intPosition = i;
            }
        }

        return intPosition;
    }

    private void closeWindow() {
        this.setVisible(false);
        this.dispose();
    }

    void setUserNameDisplay(String username) {
        this.lblWelcome.setForeground(new java.awt.Color(0, 102, 255));
        this.lblWelcome.setText("        Welcome " + username);
    }

    private void sendLogMessage(String strLog) {
        DataMssge datos = new DataMssge();

        if (jtpChatrooms.getTabCount() > 0) {
            // Get the index of the currently selected tab
            int selIndex = jtpChatrooms.getSelectedIndex();
            JPanel panel = (JPanel) jtpChatrooms.getComponentAt(selIndex);

            datos.setChatID(Integer.parseInt(panel.getName()));
            datos.setOption(Constantes.Eoption.sendLogMessage);
            datos.setUser(this.parent.getCurrentUser());
            datos.setStrLog(strLog);

            try {
                this.parent.getComm().sendRequest(datos);
            } catch (IOException ex) {
                Common.ErrorMessage("Error al notificar \"escribiendo\" : " + ex.getMessage(), ex);
                this.parent.ConnectionClosed();
            }
        }
    }

    void sentLogMessage(DataMssge datos) {
        lblErrorMessage.setText(datos.getStrLog());
    }
}
